#include "stdafx.h"
#include "Perlin.h"

float noise(float x, float y, float z) {
	perlin & myPerlin = perlin::getInstance();
	int X = (int)floorf(x) & 255, // FIND UNIT CUBE THAT
		Y = (int)floorf(y) & 255, // CONTAINS POINT.
		Z = (int)floorf(z) & 255;
	x -= floorf(x);                   // FIND RELATIVE X,Y,Z
	y -= floorf(y);                   // OF POINT IN CUBE.
	z -= floorf(z);
	float u = fade(x),              // COMPUTE FADE CURVES
		v = fade(y),              // FOR EACH OF X,Y,Z.
		w = fade(z);
	int A = myPerlin.p[X]+Y,    // HASH COORDINATES OF
		AA = myPerlin.p[A]+Z,   // THE 8 CUBE CORNERS,
		AB = myPerlin.p[A+1]+Z, 
		B = myPerlin.p[X+1]+Y, 
		BA = myPerlin.p[B]+Z, 
		BB = myPerlin.p[B+1]+Z;

	float retval = lerp(w, lerp(v, lerp(u, grad(myPerlin.p[AA], x, y, z),      // AND ADD  
		grad(myPerlin.p[BA], x-1, y, z)),    // BLENDED
		lerp(u, grad(myPerlin.p[AB], x, y-1, z),     // RESULTS
		grad(myPerlin.p[BB], x-1, y-1, z))), // FROM 8
		lerp(v, lerp(u, grad(myPerlin.p[AA+1], x, y, z-1),   // CORNERS
		grad(myPerlin.p[BA+1], x-1, y, z-1)),// OF CUBE
		lerp(u, grad(myPerlin.p[AB+1], x, y-1, z-1 ),
		grad(myPerlin.p[BB+1], x-1, y-1, z-1 ))));

	perlin::debugMaxPer = (std::max)(perlin::debugMaxPer, retval);
	perlin::debugMinPer = (std::min)(perlin::debugMinPer, retval);

	return 
		retval;
}

float perlin::debugMaxPer = 0;
float perlin::debugMinPer = 0;

perlin::perlin (void) 
{ 
	for (int i=0; i < 256 ; i++) {
		p[256+i] = p[i] = permutation[i];
	}
}
